//
// Created by Administrator on 2021/5/3.
//
/*给你一个链表的头节点 head 和一个整数 val ，请你删除链表中所有满足 Node.val == val 的节点，并返回 新的头节点 。

示例 1：
输入：head = [1,2,6,3,4,5,6], val = 6
输出：[1,2,3,4,5]

示例 2：
输入：head = [], val = 1
输出：[]

示例 3：
输入：head = [7,7,7,7], val = 7
输出：[]


提示：
列表中的节点在范围 [0, 104] 内
1 <= Node.val <= 50
0 <= k <= 50

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/remove-linked-list-elements
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。*/


#include <iostream>

//Definition for singly-linked list.
struct ListNode {
    int val;
    ListNode *next;

    ListNode() : val(0), next(nullptr) {}

    ListNode(int x) : val(x), next(nullptr) {}

    ListNode(int x, ListNode *next) : val(x), next(next) {}
};

void printList(ListNode *node) {
    auto firstNode = node;
    do {
        std::cout << firstNode->val << std::endl;
        firstNode = firstNode->next;
    } while (firstNode != nullptr);
}


class Solution {
public:
    ListNode *removeElements(ListNode *head, int val) {
        auto sentinel = new ListNode(0, head); // 哨兵节点
        ListNode *prev = sentinel, *curr = head, *toDelete = nullptr; // 前继节点 当前节点 需要删除的节点
        while (curr != nullptr) {
            if (curr->val == val) {
                prev->next = curr->next;
                toDelete = curr; // 标记为待删除
            } else prev = curr;

            curr = curr->next;   // 前进

            if (toDelete != nullptr) {  // 释放空间
                delete toDelete;
                toDelete = nullptr;
            }
        }

        ListNode *ret = sentinel->next;
        delete sentinel;
        return ret;
    }

    ListNode *removeElements2(ListNode *head, int val) {
        // 递归
        if (head == nullptr) return nullptr;
        head->next = removeElements(head->next, val);
        if (head->val == val) return head->next;
        else return head;
    }
};


int main() {
    ListNode n1{1}, n2{2}, n3{6}, n4{3}, n5{4}, n6{5}, n7{6};
    n1.next = &n2;
    n2.next = &n3;
    n3.next = &n4;
    n4.next = &n5;
    n5.next = &n6;
    n6.next = &n7;
    Solution sol;
    printList(sol.removeElements2(&n1, 6));
    return 0;
}
